<template>
    <div class="schema-table">
        <el-table v-if="schema && schema.properties" v-loading="loading" :data="tableData" class="table">
            <!-- eslint-disable-next-line vue/no-v-for-template-key -->
            <template v-for="(schemaItem, key) in schema.properties" :key="key">
                <el-table-column
                    v-if="schemaItem.option.visiable !== false"
                    :prop="key"
                    :label="schemaItem.label"
                    v-bind="schemaItem.option"
                />
            </template>
            <el-table-column
                v-if="buttons?.length > 0"
                label="操作"
                fixed="right"
                :width="operationWidth"
            >
                <template #default="scope">
                    <el-button v-for="item in buttons" link v-bind="item"
                        @click="operationHandler({ btnConfig: item, rowData: scope.row })"
                    >
                        {{ item.label }}
                    </el-button>
                </template>
            </el-table-column>
        </el-table>
        <el-row class="pagination" justify="end">
            <el-pagination
                :current-page="currentPage"
                :page-size="pageSize"
                :total="total"
                @current-change="onCurrentPageChange"
                @size-change="onPageSizeChange"
                layout="total, sizes, prev, pager, next, jumper"
            />
        </el-row>
    </div>
</template>

<script setup>
import { ref, toRefs, computed, onMounted, nextTick, watch } from 'vue'
import $curl from '$common/curl.js'
const props = defineProps({
    schema: Object,
    api: String,
    buttons: Array,
    apiParams: Object
})
const emit = defineEmits(['operate']);

const { schema, api, buttons, apiParams } = toRefs(props);
const loading = ref(false);
const tableData = ref([]);
const currentPage = ref(1);
const pageSize = ref(50);
const total = ref(0);
let timerId = null;

const operationWidth = computed(() => {
    return buttons?.value?.length > 0 ? buttons.value.reduce((pre, cur) => {
        return pre + cur.label?.length * 18;
    }, 50) : 50;
});

const operationHandler = ({ btnConfig, rowData }) => {
    emit('operate', { btnConfig, rowData });
};

const loadTableData = async () => {
    clearTimeout(timerId);
    timerId = setTimeout(async () => {
        await fetchTableData();
    }, 100);
};

const initData = () => {
    currentPage.value = 1;
    pageSize.value = 50;
    nextTick(async () => {
        await loadTableData();
    })
};

const fetchTableData = async () => {
    if (!api.value) { return; }
    showLoading();
    const res = await $curl({
        url: `${api.value}/list`,
        method: 'GET',
        query: {
            ...apiParams.value,
            currentPage: currentPage.value,
            pageSize: pageSize.value
        }
    });
    hideLoading();

    if (!res || !res.success || !Array.isArray(res.data)) {
        tableData.value = [];
        total.value = 0;
        return;
    }
    tableData.value = buildTableData(res.data);
    total.value = res?.metadata?.total || 100;
};

const buildTableData = (listData) => {
    if (!schema.value?.properties) {
        return listData
    }
    
    return listData.map(item => {
        for (const key in item) {
            const schemaItem = schema.value.properties[key]
            if (schemaItem?.option?.toFixed) {
                item[key] = item[key].toFixed && item[key].toFixed(schemaItem.option.toFixed)
            }
        }
        return item;
    })
};

const showLoading = () => {
    loading.value = true;
};

const hideLoading = () => {
    loading.value = false;
};

const onCurrentPageChange = async (page) => {
    currentPage.value = page
    await loadTableData();
};

const onPageSizeChange = async (size) => {
    pageSize.value = size;
    await loadTableData();
};

onMounted(() => {
    initData();
});

watch([schema, api, apiParams], async () => {
    initData();
}, { deep: true });

defineExpose({
    initData,
    loadTableData,
    showLoading,
    hideLoading
})
</script>

<style scoped lang="less">
.schema-table {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: auto;

    .table {
        flex: 1;
    }

    .pagination {
        margin: 10px 0;
        text-align: right;
    }
}
</style>
